package v1

import (
	"net/http"

	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"
	"github.com/unknwon/com"

	"server/global/e"
	"server/global/form"
	"server/global/response"
	"server/model"
	"server/service"
)

// @Summary 获取设备
// @Produce  json
// @Param id path int true "ID"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/device/{id} [get]
func GetDevice(c *gin.Context) {
	r := response.Gin{C: c}
	id := com.StrTo(c.Param("id")).MustInt()
	valid := validation.Validation{}
	valid.Min(id, 1, "id")

	if valid.HasErrors() {
		form.MarkErrors(valid.Errors)
		r.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}

	device := &model.Device{ID: id}
	deviceInfo, err := service.DeviceGet(*device)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_DEVICE_NOT_EXIST, nil)
		return
	}

	r.Response(http.StatusOK, e.SUCCESS, deviceInfo)
}

// @Summary 获取所有设备
// @Produce  json
// @Param status body int false "Status"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/device [get]
func GetDevices(c *gin.Context) {
	r := response.Gin{C: c}
	// 获取所有设备
	devices, err := service.DeviceGetAll()
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_DEVICE_GET_ALL, nil)
		return
	}

	r.Response(http.StatusOK, e.SUCCESS, devices)
}

type AddDeviceForm struct {
	Name     string `form:"name" valid:"MaxSize(255)"`
	Sn       string `form:"sn" valid:"MaxSize(255)"`
	Model    string `form:"model" valid:"MaxSize(255)"`
	Tag      string `form:"tag" valid:"MaxSize(255)"`
	Position string `form:"position" valid:"MaxSize(255)"`
	Pub      string `form:"pub" valid:"MaxSize(255)"`
	Sub      string `form:"sub" valid:"MaxSize(255)"`
	Value    string `form:"value" valid:"MaxSize(5000)"`
	Online   int    `form:"online" valid:"Min(0)"`
	Status   int    `form:"status" valid:"Min(0)"`
	Lock     int    `form:"lock" valid:"Min(0)"`
	Order    int    `form:"order" valid:"Min(0)"`
}

// @Summary 添加设备
// @Produce  json
// @Param id path int true "ID"
// @Param name query string true "Name"
// @Param position query string true "Position"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/device/{id} [PUT]
func AddDevice(c *gin.Context) {
	var (
		r = response.Gin{C: c}
		f AddDeviceForm
	)

	httpCode, errCode := form.BindAndValid(c, &f)
	if errCode != e.SUCCESS {
		r.Response(httpCode, errCode, nil)
		return
	}

	device := &model.Device{
		Name:     f.Name,
		Sn:       f.Sn,
		Model:    f.Model,
		Tag:      f.Tag,
		Position: f.Position,
		Pub:      f.Pub,
		Sub:      f.Sub,
		Value:    f.Value,
		Online:   f.Online,
		Status:   f.Status,
		Lock:     f.Lock,
		Order:    f.Order,
	}

	exist, _ := service.DeviceExistBySn(*device)
	if exist {
		r.Response(http.StatusOK, e.ERROR_DEVICE_EXIST, nil)
		return
	}

	// 添加设备
	err := service.DeviceAdd(*device)
	if err != nil {
		r.Response(http.StatusOK, e.ERROR_DEVICE_ADD, nil)
		return
	}

	r.Response(http.StatusOK, e.SUCCESS, nil)
}

type EditDeviceForm struct {
	ID       int    `form:"id" valid:"Min(1)"`
	Name     string `form:"name" valid:"MaxSize(255)"`
	Sn       string `form:"sn" valid:"MaxSize(255)"`
	Model    string `form:"model" valid:"MaxSize(255)"`
	Tag      string `form:"tag" valid:"MaxSize(255)"`
	Position string `form:"position" valid:"MaxSize(255)"`
	Pub      string `form:"pub" valid:"MaxSize(255)"`
	Sub      string `form:"sub" valid:"MaxSize(255)"`
	Value    string `form:"value" valid:"MaxSize(5000)"`
	Online   int    `form:"online" valid:"Min(0)"`
	Status   int    `form:"status" valid:"Min(0)"`
	Lock     int    `form:"lock" valid:"Min(0)"`
	Order    int    `form:"order" valid:"Min(0)"`
}

// @Summary 修改设备
// @Produce  json
// @Param id path int true "ID"
// @Param name query string true "Name"
// @Param position query string true "Position"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/device/{id} [PUT]
func EditDevice(c *gin.Context) {
	var (
		r = response.Gin{C: c}
		f = EditDeviceForm{ID: com.StrTo(c.Param("id")).MustInt()}
	)

	httpCode, errCode := form.BindAndValid(c, &f)
	if errCode != e.SUCCESS {
		r.Response(httpCode, errCode, nil)
		return
	}

	// 修改设备
	device := &model.Device{
		ID:       f.ID,
		Name:     f.Name,
		Sn:       f.Sn,
		Model:    f.Model,
		Tag:      f.Tag,
		Position: f.Position,
		Pub:      f.Pub,
		Sub:      f.Sub,
		Value:    f.Value,
		Online:   f.Online,
		Status:   f.Status,
		Lock:     f.Lock,
		Order:    f.Order,
	}

	_, err := service.DeviceExist(*device)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_DEVICE_CHECK_EXIST, nil)
		return
	}

	err = service.DeviceEditByID(*device)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_DEVICE_EDIT, nil)
		return
	}

	r.Response(http.StatusOK, e.SUCCESS, nil)
}

// @Summary  删除设备
// @Produce  json
// @Param id path int true "ID"
// @Success 200 {object} response.Response
// @Failure 500 {object} response.Response
// @Router /api/v1/device/{id} [DELETE]
func DeleteDevice(c *gin.Context) {
	r := response.Gin{C: c}
	id := com.StrTo(c.Param("id")).MustInt()
	valid := validation.Validation{}
	valid.Min(id, 1, "id")

	if valid.HasErrors() {
		form.MarkErrors(valid.Errors)
		r.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil)
		return
	}
	device := &model.Device{ID: id}
	exist, err := service.DeviceExist(*device)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_DEVICE_CHECK_EXIST, nil)
		return
	}
	if !exist {
		r.Response(http.StatusOK, e.ERROR_DEVICE_NOT_EXIST, nil)
		return
	}
	// 删除设备
	err = service.DeviceDelete(*device)
	if err != nil {
		r.Response(http.StatusInternalServerError, e.ERROR_DEVICE_DELETE, nil)
		return
	}

	r.Response(http.StatusOK, e.SUCCESS, nil)
}
